package com.xyy.saas.payment.merchant.core.dto;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.xyy.saas.payment.adpater.fumin.config.FuminBankCodeConfig;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.*;
import com.xyy.saas.payment.cores.vo.*;
import com.xyy.saas.payment.util.SpringUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.ArrayList;

@Data
public class AccountDto {
    public static String SUFFIX_SIGN_CHANGE = "_sign_change";

    // 开户类型 merchant-企业 personal-个人
    private String accountType;
    // 客户类型
    private String customerType;
    //--------------业务方信息--------------
    // 换签开户
    private boolean signChange = Boolean.FALSE;
    // 支付平台id
    private String userId;
    // 接口调用方的用户id
    private String businessId;
    // 接口调用方的业务类型, 支付平台分配
    private String businessIdType;
    // 账户渠道选择 目前仅支持aggregate
    private String accountChannel;
    //开会回调
    private String callback;
    //--------------企业信息--------------
    // 企业名称
    private String entName;
    // 商户简称
    private String entShortName;
    // 企业类型
    private String companyType;
    // 营业执照号
    private String enterpriseRegistrationNo;
    // 客户细类
    private String category;
    // 经营范围
    private String businessScope;
    // 注册资本金
    private String registeredCapital;
    // 注册资本金币种
    private String registeredCapitalCurrency = "CNY";
    // 注册地址
    private String registerAddress;
    // 注册省份代码
    private String provinces;
    // 注册城市代码
    private String city;
    // 注册区县代码
    private String district;
    // 客服电话
    private String customerPhone;
    // 营业执照签发日
    private String licenseTermStart;
    // 营业执照到期日
    private String licenseTermEnd;
    //--------------结算信息--------------
    // 开卡人名称
    private String accountName;
    // 卡号
    private String acct;
    // 开户行银行
    private String bankName;
    // 开户支行号
    private String branchBankCd;
    // 开户支行名称
    private String branchBankName;
    // 银行预留手机号，对私时必填
    private String mobileNo;
    // 短信验证码--
    private String activeCode;
    //--------------联系人信息--------------
    // 联系人名称
    private String contactName;
    // 联系人身份证号
    private String contactIdCard;
    // 联系人电话
    private String contactPhone;
    // 联系人邮箱
    private String contactEmail;
    // 联系人联系地址
    private String contactAddress;
    // 联系人省份代码
    private String contactProvCd;
    // 联系人城市代码
    private String contactCityCd;
    // 联系人区县代码
    private String contactContryCd;
    //--------------账号信息--------------
    // 商户登陆手机号
    private String mobile;
    // 商户登陆邮箱
    private String email;
    //--------------法人信息--------------
    // 法人姓名--
    private String corporationName;
    // 法人手机号
    private String corporatePhone;
    // 法人证件号--
    private String corporationIdNo;
    // 法人证件签发日
    private String idCardLegalTermStart;
    // 法人证件到期日
    private String idCardLegalTermEnd;
    // 法人国籍
    private String citizenship;
    // 法人性别
    private String sex;
    // 法人户籍地址
    private String domicileAddress;
    // 法人证件签发地址
    private String issuingAddress;
    //--------------股东信息--------------
    // 控股股东或者实际控制人
    private String controllerName;
    // 控股股东或者实际控制人证件种类
    private String controllerType;
    // 控股股东或者实际控制人证件号码
    private String controllerNumber;
    // 控股股东或实际控制人身份证签发日
    private String controllerStart;
    // 控股股东或实际控制人身份证到期日
    private String controllerEnd;
    //--------------受益人信息--------------
    // 受益人名称
    private String favoreeName;
    // 受益所有人身份证件种类
    private String favoreeType;
    // 受益所有人身份证件号码
    private String favoreeNumber;
    // 受益所有人身份证件签发日期
    private String favoreeStart;
    // 受益所有人身份证件到期日期
    private String favoreeEnd;
    // 受益所有人身份证件签发地址
    private String favoreeAddress;
    // 受益人联系电话--
    private String favoreePhone;
    //--------------图片信息--------------
    // 门头照（企业进件必传）
    private String shopEntrancePic;
    // 营业执照（企业进件必传）
    private String businessLicensePic;
    // 开户许可证（企业进件必传）
    private String openAccountPic;
    // 法人身份证正面（企业进件必传）
    private String idCardLegalZPic;
    // 法人身份证反面（企业进件必传）
    private String idCardLegalFPic;
    //------------授权人信息-------------
    // 授权人姓名
    private String operatorName;
    // 证件类型，默认二代身份证
    private String operatorCardType = "IDENTITY_CARD";
    // 授权人身份证号
    private String operatorIdNo;
    // 授权人手机号
    private String operatorPhone;
    // 业务授权函
    private String operatorCertificateUrl;
    // 操作开户机器IP
    private String operatorIp;
    // 操作开户机器MAC地址
    private String mac;
    /**
     * 重发验证码 0:否 1:是 仅买家需要
     */
    private Integer resendCode;

    /**
     * 参数校验
     */
    public void checkParam() throws PaymentException {
        if(StringUtils.isBlank(getAccountType())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户类型|不能为空");
        }
        if(StringUtils.isBlank(getCustomerType())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"客户类型|不能为空");
        }
        if(StringUtils.isBlank(getBusinessId())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"用户id|不能为空");
        }
        if(StringUtils.isBlank(getBusinessIdType())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"业务类型|不能为空");
        }
        if(StringUtils.isBlank(getAccountChannel())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户渠道|不能为空");
        }
        if(StringUtils.isBlank(getCallback())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户回调|不能为空");
        }
        if(StringUtils.isBlank(getEntName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"企业名称|不能为空");
        }
        if(StringUtils.isBlank(getEnterpriseRegistrationNo())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"营业执照号|不能为空");
        }
        if(StringUtils.isBlank(getAccountName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开卡人名称|不能为空");
        }
        if(StringUtils.isBlank(getAcct())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"卡号|不能为空");
        }
        if(StringUtils.isBlank(getBankName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户行银行|不能为空");
        }
        if(StringUtils.isBlank(getBranchBankCd())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户支行号|不能为空");
        }
        if(StringUtils.isBlank(getBranchBankName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"开户支行名称|不能为空");
        }
        if(StringUtils.isBlank(getContactName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"联系人名称|不能为空");
        }
        if(StringUtils.isBlank(getContactIdCard())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"联系人身份证号|不能为空");
        }
        if(StringUtils.isBlank(getContactPhone())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"联系人电话|不能为空");
        }
        if(StringUtils.isBlank(getMobile())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"商户登陆手机号|不能为空");
        }
        if(StringUtils.isBlank(getCorporationName())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"法人姓名|不能为空");
        }
        if(StringUtils.isBlank(getCorporatePhone())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"法人手机号|不能为空");
        }
        if(StringUtils.isBlank(getCorporationIdNo())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"法人证件号|不能为空");
        }
        if(StringUtils.isBlank(getOperatorIp())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"操作IP|不能为空");
        }
        if(StringUtils.isBlank(getMac())) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(),"操作MAC|不能为空");
        }
    }

    /**
     * 组装开户参数
     */
    public MerchantAccountCreateVo buildMerchantAccountCreateVo() {
        MerchantAccountCreateVo vo = new MerchantAccountCreateVo();

        if(Boolean.TRUE.equals(isSignChange())) {
            vo.setOldBusinessUserId(getBusinessId());
            setBusinessId(getBusinessId() + SUFFIX_SIGN_CHANGE);
        }

        vo.setCustomerType(getCustomerType());
        vo.setBusinessCertPicUrl(getBusinessLicensePic());
        vo.setOpenAccountLicenceUrl(getOpenAccountPic());
        vo.setIdCardFrontUrl(getIdCardLegalZPic());
        vo.setIdCardBackUrl(getIdCardLegalFPic());
        vo.setPicFmt("jpg");
        vo.setBusinessIdType(getBusinessIdType());
        vo.setBusinessUserId(getBusinessId());
        vo.setAccountChannel(getAccountChannel());

        // 法人
        ContactInfo legal = new ContactInfo();
        legal.setUserId(getBusinessId());
        legal.setContactType(ContactEnum.LEGAL_PERSON.getCode());
        legal.setContactName(getCorporationName());
        legal.setContactCertType(CertTypeEnum.ID_CARD.getCode());
        legal.setContactCertNo(getCorporationIdNo());
        legal.setContactCertValidFrom(getIdCardLegalTermStart());
        legal.setContactCertValidUntil(getIdCardLegalTermEnd());
        legal.setContactCertMobile(getCorporatePhone());

        // 联系人
        ContactInfo contactInfo = new ContactInfo();
        contactInfo.setUserId(getBusinessId());
        contactInfo.setContactType(ContactEnum.OTHER_ONE.getCode());
        contactInfo.setContactName(getContactName());
        contactInfo.setContactCertType(CertTypeEnum.ID_CARD.getCode());
        contactInfo.setContactCertNo(getContactIdCard());
        contactInfo.setContactCertMobile(getContactPhone());
        contactInfo.setContactEmail(getContactEmail());
        contactInfo.setContactAddress(getContactAddress());
        vo.setContactInfos(Lists.newArrayList(legal, contactInfo));

        ShareHolderInfoVo shareHolderInfoVo = new ShareHolderInfoVo();
        shareHolderInfoVo.setShareHolderName(getControllerName());
        shareHolderInfoVo.setShareHolderCardType(getControllerType());
        shareHolderInfoVo.setShareHolderCardNo(getControllerNumber());
        shareHolderInfoVo.setShareHolderCardStartDate(getControllerStart());
        shareHolderInfoVo.setShareHolderCardEndDate(getControllerEnd());
        vo.setShareHolderInfos(Lists.newArrayList(shareHolderInfoVo));

        BeneficiaryInfoVo beneficiaryInfoVo = new BeneficiaryInfoVo();
        beneficiaryInfoVo.setBeneficiaryName(getFavoreeName());
        beneficiaryInfoVo.setBeneficiaryLocation(getFavoreeAddress());
        beneficiaryInfoVo.setBeneficiaryPhone(getFavoreePhone());
        beneficiaryInfoVo.setBeneficiaryCardType(getFavoreeType());
        beneficiaryInfoVo.setBeneficiaryCardNo(getFavoreeNumber());
        beneficiaryInfoVo.setBeneficiaryCardStartDate(getFavoreeStart());
        beneficiaryInfoVo.setBeneficiaryCardEndDate(getFavoreeEnd());
        vo.setBeneficiaryInfos(Lists.newArrayList(beneficiaryInfoVo));

        vo.setName(getEntName());
        vo.setMobile(getMobile());
        vo.setAddress(getRegisterAddress());
        vo.setCardId(getEnterpriseRegistrationNo());
        vo.setValidFrom(getLicenseTermStart());
        vo.setValidUntil(getLicenseTermEnd());
        /**
         * Ping++通道开户用
         */
        // vo.setIndustry("");
        vo.setAccount(getAcct());
        vo.setSettleName(getAccountName());
        vo.setSettleMobile(getMobileNo());
        vo.setOpenBank(getBankName());
        /**
         * Ping++通道开户用
         */
        vo.setCardType("2");
        vo.setSubBank(getBranchBankName());
        vo.setSubBankCode(getBranchBankCd());
        vo.setMerchantCategory(getCategory());
        vo.setEnterprisePhone(getCustomerPhone());
        vo.setBusinessUserName(getEntName());

        /**
         * 回调地址
         */
        vo.setCallbackAddress(getCallback());

        /**
         * 授权人
         */
        OperatorInfo operatorInfo = new OperatorInfo();
        operatorInfo.setName(getOperatorName());
        operatorInfo.setCardNo(getOperatorIdNo());
        operatorInfo.setPhone(getOperatorPhone());
        operatorInfo.setCertificateUrl(getOperatorCertificateUrl());
        operatorInfo.setOperatorIp(getOperatorIp());
        operatorInfo.setMac(getMac());
        vo.setOperatorInfo(operatorInfo);

        /**
         * 门头照
         */
        vo.setBusinessLocationUrl(getShopEntrancePic());

        JSONObject object = new JSONObject();
        object.put("activeCode", getActiveCode());
        vo.setExtra(object.toJSONString());
        return vo;
    }

    /**
     * 组装账户修改参数
     */
    public MerchantAccountModifyDto buildMerchantAccountModifyDto() {
        MerchantAccountModifyDto dto = new MerchantAccountModifyDto();
        dto.setBusinessIdType(BusinessIdTypeEnum.type(businessIdType));
        dto.setBusinessId(businessId);
        dto.setCallback(callback);

        dto.setSource(Constants.SOURCE_OPEN_ACCOUNT);

        dto.setMobile(mobile);
        dto.setActiveCode(activeCode);

        dto.setEnterprisePhone(customerPhone);
        dto.setBusinessLocation(registerAddress);
        dto.setBusinessLocationUrl(shopEntrancePic);
        dto.setBusinessLicenseUrl(businessLicensePic);

        dto.setCorporationName(corporationName);
        dto.setCorporationIdNo(corporationIdNo);
        dto.setCorporationIdStartDate(idCardLegalTermStart);
        dto.setCorporationIdEndDate(idCardLegalTermEnd);
        dto.setCorporationIdCardFrontUrl(idCardLegalZPic);
        dto.setCorporationIdCardBackUrl(idCardLegalFPic);
        dto.setCorporationPhone(corporatePhone);

        dto.setOperatorName(operatorName);
        dto.setOperatorIdNo(operatorIdNo);
        dto.setOperatorPhone(operatorPhone);
        dto.setOperatorCertificateUrl(operatorCertificateUrl);

        dto.setShareholderName(controllerName);
        dto.setShareholderCardType(controllerType);
        dto.setShareholderCardNo(controllerNumber);
        dto.setShareholderCardStartDate(controllerStart);
        dto.setShareholderCardEndDate(controllerEnd);

        dto.setBeneficiaryName(favoreeName);
        dto.setBeneficiaryCardNo(favoreeNumber);
        dto.setBeneficiaryCardStartDate(favoreeStart);
        dto.setBeneficiaryCardEndDate(favoreeEnd);
        dto.setBeneficiaryPhone(favoreePhone);
        dto.setBeneficiaryLocation(favoreeAddress);
        return dto;
    }
    /**
     * 组装报件参数
     * @return
     */
    public CreateAllPayDto buildCreateAllPayDto() {
        CreateAllPayDto dto = new CreateAllPayDto();
        dto.setUserId(getUserId());
        dto.setBusinessId(getBusinessId());
        dto.setBusinessIdType(getBusinessIdType());
        dto.setAccountChannel(getAccountChannel());
        dto.setCallback(getCallback());

        dto.setCustMerchantNo(getUserId());

        dto.setCompanyType(getCompanyType());
        dto.setCompanyShortName(StringUtils.isNotBlank(getEntShortName()) ? getEntShortName() : getEntName());
        dto.setBusinessScope(getBusinessScope());
        dto.setRegisteredCapital(getRegisteredCapital());
        dto.setRegisteredCapitalCurrency(getRegisteredCapitalCurrency());
        dto.setRegisterAddress(getRegisterAddress());
        dto.setProvinces(getProvinces());
        dto.setCity(getCity());
        dto.setDistrict(getDistrict());
        dto.setCustomerPhone(getCustomerPhone());
        dto.setLicenseTermStart(getLicenseTermStart());
        dto.setLicenseTermEnd(getLicenseTermEnd());
        dto.setAccountName(getAccountName());
        dto.setAcct(getAcct());

        FuminBankCodeConfig fuminBankCodeConfig = SpringUtils.getBean("fuminBankCodeConfig", FuminBankCodeConfig.class);
        dto.setBankCd(fuminBankCodeConfig.getBankCodeByName(getBankName()));
        dto.setBranchBankCd(getBranchBankCd());
        dto.setBranchBankName(getBranchBankName());
        dto.setMobileNo(getMobileNo());

        dto.setContactName(getContactName());
        dto.setContactPhone(getContactPhone());
        dto.setContactEmail(getContactEmail());
        dto.setContactAddress(getContactAddress());
        dto.setContactProvCd(getContactProvCd());
        dto.setContactCityCd(getContactCityCd());
        dto.setContactContryCd(getContactContryCd());
        dto.setMobile(getMobile());
        dto.setEmail(getEmail());

        dto.setCorporatePhone(getCorporatePhone());
        dto.setIdCardLegalTermStart(getIdCardLegalTermStart());
        dto.setIdCardLegalTermEnd(getIdCardLegalTermEnd());
        dto.setCitizenship(getCitizenship());
        dto.setSex(getSex());
        dto.setDomicileAddress(getDomicileAddress());
        dto.setIssuingAddress(getIssuingAddress());

        dto.setControllerName(getControllerName());
        dto.setControllerType(getControllerType());
        dto.setControllerNumber(getControllerNumber());
        dto.setControllerStart(getControllerStart());
        dto.setControllerEnd(getControllerEnd());

        dto.setFavoreeName(getFavoreeName());
        dto.setFavoreeType(getFavoreeType());
        dto.setFavoreeNumber(getFavoreeNumber());
        dto.setFavoreeStart(getFavoreeStart());
        dto.setFavoreeEnd(getFavoreeEnd());
        dto.setFavoreeAddress(getFavoreeAddress());

        dto.setShopEntrancePic(getShopEntrancePic());
        dto.setBusinessLicensePic(getBusinessLicensePic());
        dto.setOpenAccountPic(getOpenAccountPic());
        dto.setIdCardLegalZPic(getIdCardLegalZPic());
        dto.setIdCardLegalFPic(getIdCardLegalFPic());
        dto.setOpenPayList(new ArrayList<>());
        return dto;
    }

    /**
     * 组装绑卡参数
     */
    public ApplyBankcardModifyDto buildApplyBankcardModifyDto() {
        return ApplyBankcardModifyDto.builder().
                resendCode(resendCode).
                businessIdType(BusinessIdTypeEnum.type(businessIdType)).
                businessId(businessId).
                accountId(userId).
                // 开户时绑卡业务单号默认为SH号
                businessOrderNo(isSignChange() ? businessId.substring(NumberUtils.INTEGER_ZERO, businessId.indexOf(SUFFIX_SIGN_CHANGE)) : businessId).
                callback(callback).
                source(Constants.SOURCE_OPEN_ACCOUNT).
                enterpriseName(entName).enterpriseRegistrationNo(enterpriseRegistrationNo).businessLicenseUrl(businessLicensePic).
                corporationName(corporationName).corporationIdNo(corporationIdNo).corporationIdCardFrontUrl(idCardLegalZPic).corporationIdCardBackUrl(idCardLegalFPic).corporationPhone(corporatePhone).
                contactName(contactName).contactIdCard(contactIdCard).contactPhone(contactPhone).
                accountName(accountName).acct(acct).bankName(bankName).branchBankCd(branchBankCd).branchBankName(branchBankName).mobileNo(mobileNo).
                build();
    }
}
